<?php
/**
 * Created by PhpStorm.
 * User: ari
 * Date: 12/2/14
 * Time: 2:43 PM
 */
namespace BC\User;

use BC\SiteIndex;
use CPath\Build\IBuildable;
use CPath\Build\IBuildRequest;
use CPath\Data\Map\IKeyMap;
use CPath\Data\Map\IKeyMapper;
use CPath\Render\HTML\Element\Form\HTMLInputField;
use CPath\Request\Exceptions\RequestException;
use CPath\Request\IRequest;
use CPath\Request\Validation\RequiredValidation;
use CPath\Response\Common\RedirectResponse;
use CPath\Route\IRoutable;
use CPath\Route\RouteBuilder;

class UserRoute implements IRoutable, IBuildable, IKeyMap
{
	const PATH_FORMAT = '/user/%s';
	const PARAM_NAME = 'name';

	private $mFingerprint;
	public function __construct($userFingerprint) {
		$this->mFingerprint = $userFingerprint;
	}

	public function getFingerprint() {
		return $this->mFingerprint;
	}

	public function getRequestPath() {
		return sprintf(self::PATH_FORMAT, substr($this->getFingerprint(), -8));
	}

	/**
	 * Map data to the key map
	 * @param IKeyMapper $Map the map inst to add data to
	 * @internal param \CPath\Request\IRequest $Request
	 * @internal param \CPath\Request\IRequest $Request
	 * @return void
	 */
	function mapKeys(IKeyMapper $Map) {
//		$User = $this->getUserSearch();
		$Map->map('url', $this->getRequestPath(false));
		$User = new User($this->getFingerprint());
		$Map->map('user', $User);
	}


	// Static

	public static function search(IRequest $Request, $search, $searchMode = '=') {
		$User = User::searchFirst($Request, $search, $searchMode);
		return new UserRoute($User->getFingerprint());
	}

	/**
	 * Route the request to this class object and return the object
	 * @param IRequest $Request the IRequest inst for this render
	 * @param array|null $Previous all previous response object that were passed from a handler, if any
	 * @param null|mixed $_arg [varargs] passed by route map
	 * @throws \CPath\Request\Exceptions\RequestException
	 * @return void|bool|Object returns a response object
	 * If nothing is returned (or bool[true]), it is assumed that rendering has occurred and the request ends
	 * If false is returned, this static handler will be called again if another handler returns an object
	 * If an object is returned, it is passed along to the next handler
	 */
	static function routeRequestStatic(IRequest $Request, Array &$Previous = array(), $_arg = null) {
		$Input = new HTMLInputField(self::PARAM_NAME, function (IRequest $Request, $value) {
//				if (!$value && $Request instanceof ISessionRequest)
//					$value = UserSession::getUserFingerprintFromSession($Request);

				User::searchFirst($Request, $value);

				return $value;
			}, new RequiredValidation()
		);
		$name = $Input->validate($Request);
//		if(!$name && $Request instanceof ISessionRequest) {
//			$SessionMgr = new SessionManager($Request);
//			if($SessionMgr->hasActiveUser())
//				$name = $SessionMgr->getActiveUserName();
//		}

		if(!$name)
			throw new RequestException("No user name");

		$Profile = UserRoute::search($Request, $name);

		$url = $Profile->getRequestPath(false);
		if(strpos($Request->getPath(), $url) === false)
			return new RedirectResponse($url);

		return $Profile;
	}


	/**
	 * Handle this request and render any content
	 * @param IBuildRequest $Request the build request inst for this build session
	 * @return void
	 * @build --disable 0
	 * Note: Use doctag 'build' with '--disable 1' to have this IBuildable class skipped during a build
	 */
	static function handleBuildStatic(IBuildRequest $Request) {
		$RouteBuilder = new RouteBuilder($Request, new SiteIndex());
		$RouteBuilder->writeRoute('ANY ' . sprintf(self::PATH_FORMAT, ':' . self::PARAM_NAME), __CLASS__);
		$RouteBuilder->writeRoute('ANY /profile', __CLASS__);
	}
}